package com.demo.petshop.service.impl;

import com.demo.petshop.entity.*;
import com.demo.petshop.mapper.*;
import com.demo.petshop.service.ProductReviewsService;
import com.demo.petshop.service.ProductsService;
import com.demo.petshop.service.StoreFollowersService;
import com.demo.petshop.util.Result;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

import static com.demo.petshop.entity.table.CategoriesTableDef.CATEGORIES;
import static com.demo.petshop.entity.table.FavoritesTableDef.FAVORITES;
import static com.demo.petshop.entity.table.ProductReviewsTableDef.PRODUCT_REVIEWS;
import static com.demo.petshop.entity.table.ProductSpecsTableDef.PRODUCT_SPECS;
import static com.demo.petshop.entity.table.ProductsTableDef.PRODUCTS;
import static com.demo.petshop.entity.table.StoreFollowersTableDef.STORE_FOLLOWERS;
import static com.demo.petshop.entity.table.UsersTableDef.USERS;
import static com.demo.petshop.entity.table.VideoCommentsTableDef.VIDEO_COMMENTS;
import static com.demo.petshop.entity.table.VideoLikesTableDef.VIDEO_LIKES;
import static com.demo.petshop.entity.table.VideoProductsTableDef.VIDEO_PRODUCTS;
import static com.demo.petshop.entity.table.VideoTagRelationTableDef.VIDEO_TAG_RELATION;
import static com.demo.petshop.entity.table.VideosTableDef.VIDEOS;
import static com.demo.petshop.entity.table.StoresTableDef.STORES;

/**
 *  服务层实现。
 *
 * @author lenovo
 * @since 2025-06-11
 */
@Service
public class ProductsServiceImpl extends ServiceImpl<ProductsMapper, Products> implements ProductsService {
    @Autowired
    private ProductsMapper productsMapper;
    @Autowired
    private ProductSpecsMapper productSpecsMapper;
    @Autowired
    private ProductReviewsService productReviewsService;
    @Autowired
    private UsersMapper usersMapper;
    @Autowired
    private VideosMapper videosMapper;
    @Autowired
    private StoresMapper storesMapper;
    @Autowired
    private StoreFollowersMapper storeFollowersMapper;
    @Autowired
    private VideoProductsMapper videoProductsMapper;
    @Autowired
    private VideoTagRelationMapper videoTagRelationMapper;
    @Autowired
    private VideoLikesMapper videoLikesMapper;
    @Autowired
    private VideoCommentsMapper videoCommentsMapper;
    @Autowired
    private FavoritesMapper favoritesMapper;
    private int getUserId() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        return loginUser.getUser().getUserId();
    }
    @Override
    public Object search(String keyword){
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper
                .select(PRODUCTS.ALL_COLUMNS)
                .from(PRODUCTS)
                .join(CATEGORIES).on(CATEGORIES.CATEGORY_ID.eq(PRODUCTS.CATEGORY_ID))
                .where(PRODUCTS.NAME.like(keyword)).and(PRODUCTS.DELETE.eq(0));
        return Result.success(productsMapper.selectListByQuery(queryWrapper));
    }

    @Override
    public Object category(int categoryId){
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper
                .select(PRODUCTS.ALL_COLUMNS)
                .from(PRODUCTS)
                .join(CATEGORIES).on(CATEGORIES.CATEGORY_ID.eq(PRODUCTS.CATEGORY_ID))
                .where(PRODUCTS.CATEGORY_ID.eq(categoryId).when(categoryId>0))
                .and(PRODUCTS.DELETE.eq(0));
        return Result.success(productsMapper.selectListByQuery(queryWrapper));
    }

    @Override
    public Object product(int productId){
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper
                .select(PRODUCTS.ALL_COLUMNS)
                .from(PRODUCTS)
                .join(CATEGORIES).on(CATEGORIES.CATEGORY_ID.eq(PRODUCTS.CATEGORY_ID))
                .where(PRODUCTS.PRODUCT_ID.eq(productId));
        return Result.success(productsMapper.selectOneByQuery(queryWrapper));
    }

    @Override
    public Object getStoreByProductId(int productId){
        QueryWrapper queryWrapper =new QueryWrapper();
        queryWrapper
                .select(STORES.ALL_COLUMNS)
                .from(STORES)
                .join(PRODUCTS).on(PRODUCTS.STORE_ID.eq(STORES.STORE_ID))
                .where(PRODUCTS.PRODUCT_ID.eq(productId));
        return Result.success(storesMapper.selectOneByQuery(queryWrapper));
    }
    @Override
    public Object productList(){
       return productsMapper.selectListByQuery(
               new QueryWrapper()
                       .where(PRODUCTS.DELETE.eq(0))
       );
    }

    @Override
    public Object getProductsListByMemberLevel() {
        int userId=getUserId();
        Users users = usersMapper.selectOneById(userId);
        QueryWrapper queryWrapper=new QueryWrapper();
        if("-1".equals(users.getMemberLevel()))
        {
            queryWrapper.select(STORE_FOLLOWERS.ALL_COLUMNS).from(STORE_FOLLOWERS)
                    .where(STORE_FOLLOWERS.USER_ID.eq(userId));
            List<StoreFollowers> storeFollowers = storeFollowersMapper.selectListByQuery(queryWrapper);
            queryWrapper.select(PRODUCTS.ALL_COLUMNS).from(PRODUCTS);
            List<Products> productsList=new ArrayList<>();
            for (StoreFollowers storeFollowers1:storeFollowers){
                QueryWrapper queryWrapper1=new QueryWrapper();
                queryWrapper1.select(PRODUCTS.ALL_COLUMNS).from(PRODUCTS)
                        .where(PRODUCTS.STORE_ID.eq(storeFollowers1.getStoreId()))
                        .and(PRODUCTS.DELETE.eq(0));
                List<Products> products = productsMapper.selectListByQuery(queryWrapper1);
                productsList.addAll(products);
            }
            for (Products products1:productsList){
                QueryWrapper queryWrapper1=new QueryWrapper();
                queryWrapper1.select(PRODUCT_SPECS.ALL_COLUMNS).from(PRODUCT_SPECS)
                        .where(PRODUCT_SPECS.PRODUCT_ID.eq(products1.getProductId()))
                        .and(PRODUCT_SPECS.DELETED.eq(0));
                List<ProductSpecs> productSpecs = productSpecsMapper.selectListByQuery(queryWrapper1);
                List<String> productSpecList=new ArrayList<>();
                for(ProductSpecs productSpecs1:productSpecs){
                    productSpecList.add(productSpecs1.getValue());
                }
                products1.setSpecValueList(productSpecList);
            }
            return productsList;
        }
        else {
            List<Products> products = productsMapper.selectListByQuery(
                    new QueryWrapper()
                            .where(PRODUCTS.DELETE.eq(0))
            );
            for (Products products1:products){
                QueryWrapper queryWrapper1=new QueryWrapper();
                queryWrapper1.select(PRODUCT_SPECS.ALL_COLUMNS).from(PRODUCT_SPECS)
                        .where(PRODUCT_SPECS.PRODUCT_ID.eq(products1.getProductId()))
                        .and(PRODUCT_SPECS.DELETED.eq(0));
                List<ProductSpecs> productSpecs = productSpecsMapper.selectListByQuery(queryWrapper1);
                List<String> productSpecList=new ArrayList<>();
                for(ProductSpecs productSpecs1:productSpecs){
                    productSpecList.add(productSpecs1.getValue());
                }
                products1.setSpecValueList(productSpecList);
            }
            return products;
        }

    }

    @Override
    public Object createProduct(Products products) {
        Instant instant = Instant.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
        String formatted = LocalDateTime.ofInstant(instant, ZoneId.systemDefault())
                .format(formatter);
        products.setCreatedAt(formatted);
        products.setSalesCount(0);
        products.setRating(0.0);
        products.setReviewCount(0);
        products.setDelete(0);
        productsMapper.insert(products);
        QueryWrapper queryWrapper =new QueryWrapper();
        queryWrapper.select(PRODUCTS.ALL_COLUMNS).from(PRODUCTS)
                .where(PRODUCTS.STORE_ID.eq(products.getStoreId()))
                .orderBy(PRODUCTS.PRODUCT_ID,false)
                .limit(1);
        Products products1 = productsMapper.selectOneByQuery(queryWrapper);
        List<String> specValueList = products.getSpecValueList();
        ProductSpecs productSpecs=new ProductSpecs();
        productSpecs.setProductId(products.getProductId());
        productSpecs.setName("规格");
        for (String specValueL:specValueList){
            productSpecs.setValue(specValueL);
            productSpecs.setDeleted(0);
            productSpecs.setProductId(products1.getProductId());
            productSpecsMapper.insert(productSpecs);
        }
        return true;
    }

    @Override
    public Object delete(Integer productId) {
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper.select(VIDEO_PRODUCTS.ALL_COLUMNS).from(VIDEO_PRODUCTS)
                .where(VIDEO_PRODUCTS.PRODUCT_ID.eq(productId));
        List<VideoProducts> videoProducts = videoProductsMapper.selectListByQuery(queryWrapper);
        Products products = productsMapper.selectOneById(productId);
        products.setDelete(1);
        productsMapper.update(products);
        QueryWrapper queryWrapper2=new QueryWrapper();
        queryWrapper2.select(PRODUCT_SPECS.ALL_COLUMNS).from(PRODUCT_SPECS)
                .where(PRODUCT_SPECS.PRODUCT_ID.eq(productId))
                .and(PRODUCT_SPECS.DELETED.eq(0));
        List<ProductSpecs> productSpecs = productSpecsMapper.selectListByQuery(queryWrapper2);
        for (ProductSpecs productSpecs1:productSpecs)
        {
            productSpecs1.setDeleted(1);
            productSpecsMapper.update(productSpecs1);
        }
        QueryWrapper queryWrapper3=new QueryWrapper();
        queryWrapper3.from(FAVORITES).where(FAVORITES.PRODUCT_ID.eq(productId));
        favoritesMapper.deleteByQuery(queryWrapper3);
        for (VideoProducts videoProducts1:videoProducts)
        {

            int videoId=videoProducts1.getVideoId();
            videosMapper.deleteById(videoId);
            QueryWrapper queryWrapper1=new QueryWrapper();
            queryWrapper1.select(VIDEO_PRODUCTS.ALL_COLUMNS).from(VIDEO_PRODUCTS)
                    .where(VIDEO_PRODUCTS.VIDEO_ID.eq(videoId));
            videoProductsMapper.deleteByQuery(queryWrapper1);
            queryWrapper1=new QueryWrapper();
            queryWrapper1.select(VIDEO_TAG_RELATION.ALL_COLUMNS).from(VIDEO_TAG_RELATION)
                    .where(VIDEO_TAG_RELATION.VIDEO_ID.eq(videoId));
            videoTagRelationMapper.deleteByQuery(queryWrapper1);
            queryWrapper1=new QueryWrapper();
            queryWrapper1.select(VIDEO_LIKES.ALL_COLUMNS).from(VIDEO_LIKES)
                    .where(VIDEO_LIKES.VIDEO_ID.eq(videoId));
            videoLikesMapper.deleteByQuery(queryWrapper1);
            queryWrapper1=new QueryWrapper();
            queryWrapper1.select(VIDEO_COMMENTS.ALL_COLUMNS).from(VIDEO_COMMENTS)
                    .where(VIDEO_COMMENTS.VIDEO_ID.eq(videoId));
            videoCommentsMapper.deleteByQuery(queryWrapper1);
            queryWrapper1=new QueryWrapper();
            queryWrapper1.select(FAVORITES.ALL_COLUMNS).from(FAVORITES)
                    .where(FAVORITES.VIDEO_ID.eq(videoId));
            favoritesMapper.deleteByQuery(queryWrapper1);
        }
        return true;
    }

    @Override
    public Object orderByPrice(int categoryId){
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper
                .select(PRODUCTS.ALL_COLUMNS)
                .from(PRODUCTS)
                .join(CATEGORIES).on(CATEGORIES.CATEGORY_ID.eq(PRODUCTS.CATEGORY_ID))
                .where(PRODUCTS.CATEGORY_ID.eq(categoryId).when(categoryId>0))
                .and(PRODUCTS.DELETE.eq(0))
                .orderBy(PRODUCTS.PRICE,true);
        return Result.success(productsMapper.selectListByQuery(queryWrapper));
    }

    @Override
    public Object orderBySale(int categoryId){
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper
                .select(PRODUCTS.ALL_COLUMNS)
                .from(PRODUCTS)
                .join(CATEGORIES).on(CATEGORIES.CATEGORY_ID.eq(PRODUCTS.CATEGORY_ID))
                .where(PRODUCTS.CATEGORY_ID.eq(categoryId).when(categoryId>0))
                .and(PRODUCTS.DELETE.eq(0))
                .orderBy(PRODUCTS.SALES_COUNT,false);
        return Result.success(productsMapper.selectListByQuery(queryWrapper));
    }

    @Override
    public Object reOrderByPrice(int categoryId){
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper
                .select(PRODUCTS.ALL_COLUMNS)
                .from(PRODUCTS)
                .join(CATEGORIES).on(CATEGORIES.CATEGORY_ID.eq(PRODUCTS.CATEGORY_ID))
                .where(PRODUCTS.CATEGORY_ID.eq(categoryId).when(categoryId>0))
                .and(PRODUCTS.DELETE.eq(0))
                .orderBy(PRODUCTS.PRICE,false);
        return Result.success(productsMapper.selectListByQuery(queryWrapper));
    }

    @Override
    public Object getProducts(int storeId) {
        QueryWrapper queryWrapper= new QueryWrapper();
        queryWrapper.select(PRODUCTS.ALL_COLUMNS).from(PRODUCTS)
                .where(PRODUCTS.STORE_ID.eq(storeId))
                .and(PRODUCTS.DELETE.eq(0));
        List<Products> products = productsMapper.selectListByQuery(queryWrapper);
        for (Products products1:products){
            QueryWrapper queryWrapper1=new QueryWrapper();
            queryWrapper1.select(PRODUCT_SPECS.ALL_COLUMNS).from(PRODUCT_SPECS)
                    .where(PRODUCT_SPECS.PRODUCT_ID.eq(products1.getProductId()))
                    .and(PRODUCT_SPECS.DELETED.eq(0));
            List<ProductSpecs> productSpecs = productSpecsMapper.selectListByQuery(queryWrapper1);
            List<String> productSpecList=new ArrayList<>();
            for(ProductSpecs productSpecs1:productSpecs){
                productSpecList.add(productSpecs1.getValue());
            }
            products1.setSpecValueList(productSpecList);
        }
        return Result.success(products);
    }

    @Override
    public Object getByVideoId(int videoId) {
        return Result.success(productsMapper.selectListByQuery(
                new QueryWrapper()
                        .select(PRODUCTS.ALL_COLUMNS)
                        .from(PRODUCTS)
                        .leftJoin(VIDEO_PRODUCTS).on(VIDEO_PRODUCTS.PRODUCT_ID.eq(PRODUCTS.PRODUCT_ID))
                        .where(VIDEO_PRODUCTS.VIDEO_ID.eq(videoId))
        ));
    }

    @Override
    public Object getProductSpec(int productId){
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper
                .select(PRODUCT_SPECS.ALL_COLUMNS)
                .from(PRODUCT_SPECS)
                .where(PRODUCT_SPECS.PRODUCT_ID.eq(productId))
                .and(PRODUCT_SPECS.DELETED.eq(0));
        return Result.success(productSpecsMapper.selectListByQuery(queryWrapper));
    }

    @Override
    public Object getProductReviews(Integer productId) {
        List<ProductReviews> products = productReviewsService.getByProductId(productId);
        for (ProductReviews product : products){
            QueryWrapper queryWrapper=new QueryWrapper();
            queryWrapper.select(USERS.ALL_COLUMNS).from(USERS)
                    .leftJoin(PRODUCT_REVIEWS).on(PRODUCT_REVIEWS.USER_ID.eq(USERS.USER_ID))
                    .where(PRODUCT_REVIEWS.REVIEW_ID.eq(product.getReviewId())).groupBy(USERS.USER_ID)
                    .orderBy(PRODUCT_REVIEWS.REVIEW_ID, false);
            Users users = usersMapper.selectOneByQuery(queryWrapper);
            product.setAvatar(users.getAvatar());
            product.setUsername(users.getUsername());
        }
        return products;
    }

    @Override
    public Object updateProduct(Products products) {
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper.select(PRODUCT_SPECS.ALL_COLUMNS).from(PRODUCT_SPECS)
                .where(PRODUCT_SPECS.PRODUCT_ID.eq(products.getProductId()))
                .and(PRODUCT_SPECS.DELETED.eq(0));
        List<ProductSpecs> productSpecs1 = productSpecsMapper.selectListByQuery(queryWrapper);
        for (ProductSpecs productSpecs:productSpecs1){
            productSpecs.setDeleted(1);
            productSpecsMapper.update(productSpecs);
        }
        List<String> specsList=products.getSpecValueList();
        ProductSpecs productSpecs=new ProductSpecs();
        productSpecs.setName("规格");
        productSpecs.setProductId(products.getProductId());
        for (String s:specsList){
            productSpecs.setValue(s);
            productSpecs.setDeleted(0);
            productSpecsMapper.insert(productSpecs);
        }
        return Result.success(productsMapper.update(products));
    }

    @Override
    public Object getProductVideos(int productId){
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper
                .from(VIDEOS)
                .join(VIDEO_PRODUCTS).on(VIDEO_PRODUCTS.VIDEO_ID.eq(VIDEOS.VIDEO_ID))
                .where(VIDEO_PRODUCTS.PRODUCT_ID.eq(productId));
        return Result.success(videosMapper.selectListByQuery(queryWrapper));
    }

    @Override
    public Object searchOfStoreId(String keyword, int storeId) {
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper
                .select(PRODUCTS.ALL_COLUMNS)
                .from(PRODUCTS)
                .join(CATEGORIES).on(CATEGORIES.CATEGORY_ID.eq(PRODUCTS.CATEGORY_ID))
                .join(STORES).on(STORES.STORE_ID.eq(PRODUCTS.STORE_ID))
                .where(PRODUCTS.NAME.like(keyword))
                .and(STORES.STORE_ID.eq(storeId))
                .and(PRODUCTS.DELETE.eq(0));
        return Result.success(productsMapper.selectListByQuery(queryWrapper));
    }

    @Override
    public Object categoryOfStoreId(int categoryId, int storeId) {
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper
                .select(PRODUCTS.ALL_COLUMNS)
                .from(PRODUCTS)
                .join(CATEGORIES).on(CATEGORIES.CATEGORY_ID.eq(PRODUCTS.CATEGORY_ID))
                .join(STORES).on(STORES.STORE_ID.eq(PRODUCTS.STORE_ID))
                .where(PRODUCTS.CATEGORY_ID.eq(categoryId).when(categoryId>0))
                .and(STORES.STORE_ID.eq(storeId));
        return Result.success(productsMapper.selectListByQuery(queryWrapper));
    }

    @Override
    public Object orderByPriceOfStoreId(int categoryId, int storeId) {
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper
                .select(PRODUCTS.ALL_COLUMNS)
                .from(PRODUCTS)
                .join(CATEGORIES).on(CATEGORIES.CATEGORY_ID.eq(PRODUCTS.CATEGORY_ID))
                .join(STORES).on(STORES.STORE_ID.eq(PRODUCTS.STORE_ID))
                .where(PRODUCTS.CATEGORY_ID.eq(categoryId).when(categoryId>0))
                .and(STORES.STORE_ID.eq(storeId))
                .orderBy(PRODUCTS.PRICE,true)
                .and(PRODUCTS.DELETE.eq(0));
        return Result.success(productsMapper.selectListByQuery(queryWrapper));
    }

    @Override
    public Object orderBySaleOfStoreId(int categoryId, int storeId) {
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper
                .select(PRODUCTS.ALL_COLUMNS)
                .from(PRODUCTS)
                .join(CATEGORIES).on(CATEGORIES.CATEGORY_ID.eq(PRODUCTS.CATEGORY_ID))
                .join(STORES).on(STORES.STORE_ID.eq(PRODUCTS.STORE_ID))
                .where(PRODUCTS.CATEGORY_ID.eq(categoryId).when(categoryId>0))
                .and(STORES.STORE_ID.eq(storeId))
                .orderBy(PRODUCTS.SALES_COUNT,false)
                .and(PRODUCTS.DELETE.eq(0));
        return Result.success(productsMapper.selectListByQuery(queryWrapper));
    }

    @Override
    public Object reOrderByPriceOfStoreId(int categoryId, int storeId) {
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper
                .select(PRODUCTS.ALL_COLUMNS)
                .from(PRODUCTS)
                .join(CATEGORIES).on(CATEGORIES.CATEGORY_ID.eq(PRODUCTS.CATEGORY_ID))
                .join(STORES).on(STORES.STORE_ID.eq(PRODUCTS.STORE_ID))
                .where(PRODUCTS.CATEGORY_ID.eq(categoryId).when(categoryId>0))
                .and(STORES.STORE_ID.eq(storeId))
                .and(STORES.STORE_ID.eq(storeId))
                .orderBy(PRODUCTS.PRICE,false);
        return Result.success(productsMapper.selectListByQuery(queryWrapper));
    }
}
